package oa.hleast.xswl.service.store.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import oa.hleast.common.constant.AuthConstant;
import oa.hleast.common.web.exception.BizException;
import oa.hleast.common.web.util.RequestUtils;
import oa.hleast.xswl.common.constant.CommonConstant;
import oa.hleast.xswl.common.constant.ReviewStatusEnum;
import oa.hleast.xswl.mapper.store.StoreInfoMapper;
import oa.hleast.xswl.pojo.domain.StorePayInfo;
import oa.hleast.xswl.pojo.domain.SysCommonConfig;
import oa.hleast.xswl.pojo.domain.SysUser;
import oa.hleast.xswl.pojo.domain.SysUserRole;
import oa.hleast.xswl.pojo.domain.store.StoreInfo;
import oa.hleast.xswl.pojo.dto.store.StoreInfoDto;
import oa.hleast.xswl.pojo.form.store.OpenShopForm;
import oa.hleast.xswl.pojo.form.store.StoreInfoForm;
import oa.hleast.xswl.pojo.form.store.StoreRegisteredForm;
import oa.hleast.xswl.pojo.vo.store.BaseStoreInfo;
import oa.hleast.xswl.service.ISysCommonConfigService;
import oa.hleast.xswl.service.ISysUserRoleService;
import oa.hleast.xswl.service.ISysUserService;
import oa.hleast.xswl.service.pms.IPmsSpuService;
import oa.hleast.xswl.service.store.StoreInfoService;
import oa.hleast.xswl.service.store.StorePayInfoService;
import oa.hleast.xswl.service.store.StoreReviewLogService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author: 302
 * @date: 2021-10-16 14:56:15
 * @description: 商家信息表(StoreInfo)接口实现
 */

@Slf4j
@AllArgsConstructor
@Transactional
@Service("storeInfoService")
public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo> implements StoreInfoService {

    private final PasswordEncoder passwordEncoder;
    private final ISysUserService sysUserService;
    private final IPmsSpuService spuService;
    private final StoreReviewLogService storeReviewLogService;
    private final StorePayInfoService storePayInfoService;
    private final ISysUserRoleService iSysUserRoleService;
    private final ISysCommonConfigService sysCommonConfigService;

    /**
     * 获取店铺及支付基本信息
     */
    @Override
    public StoreInfoDto getStoreInfoDtoById(Long id) {
        StoreInfo storeInfo = this.getById(id);
        StoreInfoDto storeInfoDto = new StoreInfoDto();
        BeanUtil.copyProperties(storeInfo, storeInfoDto);

        StorePayInfo storePayInfo = storePayInfoService.getStorePayByStoreId(id);

        storeInfoDto.setStorePayInfo(storePayInfo);

        return storeInfoDto;
    }

    @Override
    public boolean updateStoreInfo(StoreInfoForm body) {
        StoreInfo storeInfo = this.getById(body.getId());
        BeanUtil.copyProperties(body, storeInfo);

        storeInfo.setId(body.getId());
        storeInfo.setStoreName(body.getStoreName());
        storeInfo.setLegalPersonName(body.getLegalPersonName());
        storeInfo.setLegalPersonPhone(body.getLegalPersonPhone());

        boolean updateStoreInfo = this.updateById(storeInfo);

        Long sysUserId = storeInfo.getSysUserId();
        boolean update = sysUserService.update(new LambdaUpdateWrapper<SysUser>()
                .set(SysUser::getNickname, body.getLegalPersonName())
                .eq(SysUser::getId, sysUserId)
        );

        return updateStoreInfo && update;
    }

    @Override
    public BaseStoreInfo baseInfo(Long id) {
        StoreInfo storeInfo = this.getById(id);
        BaseStoreInfo baseStoreInfo = new BaseStoreInfo();
        BeanUtil.copyProperties(storeInfo, baseStoreInfo);
        return baseStoreInfo;
    }


    @Override
    public Boolean registeredByPC(StoreRegisteredForm form) {
        return registered(form, 0);
    }

    @Override
    public Boolean registeredByApp(StoreRegisteredForm form) {
        return registered(form, 1);
    }

    @Override
    public Boolean registeredByProxy(StoreRegisteredForm form) {
        return registered(form, 2);
    }

    @Override
    public Boolean closeShop(String id) {
        // 清空该店铺所有的产品
        spuService.closeStoreSpu(id);

        boolean update = this.update(new LambdaUpdateWrapper<StoreInfo>()
                .set(StoreInfo::getStoreEventStatus, 1)
                .eq(StoreInfo::getId, id));

        return update;
    }

    @Override
    public Boolean openShop(OpenShopForm form) {
        Long id = form.getId();

        boolean update = this.update(new LambdaUpdateWrapper<StoreInfo>()
                .set(StoreInfo::getStoreEventStatus, 0)
                .eq(StoreInfo::getId, id));

        return update;
    }

    @Override
    public boolean reviewPass(Long id, Long userId) {

        StoreInfo storeInfo = this.getById(id);
        if (!ReviewStatusEnum.UN_KNOWN.getCode().equals((int) storeInfo.getReviewStatus())) {
            throw new BizException("您已经审核过了,请勿重复审核");
        }

        // 注册账号
        SysUser sysUser = SysUser.builder()
                .username(storeInfo.getRegisteredUserName())
                .nickname(storeInfo.getLegalPersonName())
                .password(storeInfo.getRegisteredPassword())
                .mobile(storeInfo.getLegalPersonPhone())
                .storeId(id)
                .haveStore(true)
                .status(1)
                .build();
        boolean saveUser = true;
        try {
            saveUser = sysUserService.save(sysUser);
            log.info("sysUser = {}", sysUser);
        } catch (Exception e) {
            log.info("e = {}", e.getMessage(), e);
            throw new BizException("注册账户异常,请联系管理员");
        }


        // 审核通过
        boolean reviewStatus = this.update(new LambdaUpdateWrapper<StoreInfo>()
                .eq(StoreInfo::getId, id)
                .set(StoreInfo::getSysUserId, sysUser.getId())
                .set(StoreInfo::getReviewStatus, ReviewStatusEnum.PASS.getCode()));

        // 记录操作日志
        boolean reviewLogSave = storeReviewLogService.saveLog(userId, ReviewStatusEnum.PASS.getCode(), id, "");

        // 添加商户权限
        SysCommonConfig config = sysCommonConfigService.getByConfigKey(CommonConstant.SHOPKEEPER_ROLES_ID);
        Long rolesId = new Long(config.getValue());
        boolean saveRoles = iSysUserRoleService.save(new SysUserRole().setUserId(sysUser.getId()).setRoleId(rolesId));

        return reviewStatus && reviewLogSave && saveUser && saveRoles;
    }

    @Override
    public boolean reviewNotPass(Long userId, Long storeId, String remark) {

        // 审核驳回
        boolean updateStatus = this.update(new LambdaUpdateWrapper<StoreInfo>()
                .eq(StoreInfo::getId, storeId)
                .set(StoreInfo::getReviewStatus, ReviewStatusEnum.NO_PASS.getCode())
                .set(StoreInfo::getReviewRemark, remark));
        // 记录操作日志
        boolean reviewLogSave = storeReviewLogService.saveLog(userId, ReviewStatusEnum.NO_PASS.getCode(), storeId, remark);

        return updateStatus && reviewLogSave;
    }

    @Override
    public Boolean registered(StoreRegisteredForm form, Integer registeredSource) {
        Long userId = RequestUtils.getUserId();
        log.info("userId = {}", userId);

        String userName = form.getUserName();
        sysUserService.checkRepeatUserName(userName);

        // 注册店铺
        StoreInfo storeInfo = new StoreInfo();
        BeanUtil.copyProperties(form, storeInfo);
        storeInfo.setRegisteredSource(registeredSource);
        storeInfo.setRegisteredUserName(form.getUserName());
        storeInfo.setRegisteredPassword(passwordEncoder.encode(form.getPassword()).replace(AuthConstant.BCRYPT, Strings.EMPTY));
        if (2 == registeredSource) {
            SysUser sysUser = sysUserService.getById(userId);
            storeInfo.setGmuNameCreate(sysUser.getUsername());
            storeInfo.setGmuCreate(userId);
        }

        boolean saveStore = this.save(storeInfo);
        log.info("storeInfo = {}", storeInfo);

        // 添加店铺支付信息
        boolean paySave = storePayInfoService.save(StorePayInfo.builder().storeId(storeInfo.getId()).build());

        return saveStore && paySave;
    }


}
